<template>
  <div class="category-management">
    <!-- 搜索区域 -->
    <div class="search-container">
      <el-card shadow="never">
        <el-form :model="searchForm" inline>
          <el-form-item label="分类名称">
            <el-input
              v-model="searchForm.name"
              placeholder="请输入分类名称"
              clearable
              style="width: 200px"
            />
          </el-form-item>
          <el-form-item label="状态">
            <el-select
              v-model="searchForm.status"
              placeholder="选择状态"
              clearable
              style="width: 120px"
            >
              <el-option label="启用" :value="1" />
              <el-option label="禁用" :value="0" />
            </el-select>
          </el-form-item>
          <el-form-item label="创建时间">
            <el-date-picker
              v-model="dateRange"
              type="datetimerange"
              range-separator="至"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
              format="YYYY-MM-DD HH:mm:ss"
              value-format="YYYY-MM-DD HH:mm:ss"
              style="width: 350px"
            />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="handleSearch">
              <el-icon><Search /></el-icon>
              搜索
            </el-button>
            <el-button @click="handleReset">
              <el-icon><Refresh /></el-icon>
              重置
            </el-button>
          </el-form-item>
        </el-form>
      </el-card>
    </div>

    <!-- 操作区域 -->
    <div class="operation-container">
      <el-card shadow="never">
        <div class="operation-bar">
          <div class="left-operations">
            <el-button type="primary" @click="handleCreate">
              <el-icon><Plus /></el-icon>
              新建分类
            </el-button>
            <el-button
              type="success"
              :disabled="!hasSelection"
              @click="handleBatchOperation('ENABLE')"
            >
              <el-icon><Select /></el-icon>
              批量启用
            </el-button>
            <el-button
              type="warning"
              :disabled="!hasSelection"
              @click="handleBatchOperation('DISABLE')"
            >
              <el-icon><Close /></el-icon>
              批量禁用
            </el-button>
            <el-button
              type="danger"
              :disabled="!hasSelection"
              @click="handleBatchOperation('DELETE')"
            >
              <el-icon><Delete /></el-icon>
              批量删除
            </el-button>
          </div>
          <div class="right-operations">
            <el-button @click="handleRefresh">
              <el-icon><Refresh /></el-icon>
              刷新
            </el-button>
            <el-button @click="showStatistics = true">
              <el-icon><DataAnalysis /></el-icon>
              统计信息
            </el-button>
          </div>
        </div>
      </el-card>
    </div>

    <!-- 数据表格 -->
    <div class="table-container">
      <el-card shadow="never">
        <el-table
          v-loading="loading"
          :data="tableData"
          stripe
          border
          @selection-change="handleSelectionChange"
          @sort-change="handleSortChange"
        >
          <el-table-column type="selection" width="55" />
          <el-table-column prop="id" label="ID" width="80" sortable="custom" />
          <el-table-column prop="name" label="分类名称" min-width="150">
            <template #default="{ row }">
              <div class="category-name">
                <img
                  v-if="row.icon"
                  :src="CategoryManagementUtils.generateIconUrl(row.icon)"
                  class="category-icon"
                  @error="handleIconError"
                />
                <span>{{ row.name }}</span>
              </div>
            </template>
          </el-table-column>
          <el-table-column
            prop="description"
            label="描述"
            min-width="200"
            show-overflow-tooltip
          />
          <el-table-column
            prop="sortOrder"
            label="排序"
            width="160"
            sortable="custom"
          >
            <template #default="{ row }">
              <div class="sort-input-container">
                <el-input-number
                  v-model="row.sortOrder"
                  :min="0"
                  :max="9999"
                  size="small"
                  :class="{ editing: editingSortIds.has(row.id) }"
                  @change="handleSortOrderChange(row)"
                />
                <el-icon
                  v-if="updatingSortIds.has(row.id)"
                  class="is-loading sort-loading"
                  title="正在保存..."
                >
                  <Loading />
                </el-icon>
                <el-icon
                  v-else-if="editingSortIds.has(row.id)"
                  class="sort-pending"
                  title="待保存"
                >
                  <Clock />
                </el-icon>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="status" label="状态" width="100">
            <template #default="{ row }">
              <el-tag
                :type="CategoryManagementUtils.getStatusTagType(row.status)"
              >
                {{ CategoryManagementUtils.getStatusText(row.status) }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="articleCount" label="文章数量" width="120">
            <template #default="{ row }">
              <div class="article-count">
                <span class="total">{{
                  CategoryManagementUtils.formatArticleCount(
                    row.articleCount || 0
                  )
                }}</span>
                <div
                  v-if="row.publishedArticleCount !== undefined"
                  class="detail"
                >
                  <span class="published"
                    >已发布: {{ row.publishedArticleCount }}</span
                  >
                  <span class="draft">草稿: {{ row.draftArticleCount }}</span>
                </div>
              </div>
            </template>
          </el-table-column>
          <el-table-column
            prop="createTime"
            label="创建时间"
            width="180"
            sortable="custom"
          />
          <el-table-column label="操作" width="200" fixed="right">
            <template #default="{ row }">
              <el-button type="primary" size="small" @click="handleEdit(row)">
                编辑
              </el-button>
              <el-button
                v-if="row.status === 0"
                type="success"
                size="small"
                @click="handleEnable(row)"
              >
                启用
              </el-button>
              <el-button
                v-if="row.status === 1"
                type="warning"
                size="small"
                @click="handleDisable(row)"
              >
                禁用
              </el-button>
              <el-button type="danger" size="small" @click="handleDelete(row)">
                删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>

        <!-- 分页 -->
        <div class="pagination-container">
          <el-pagination
            v-model:current-page="pagination.current"
            v-model:page-size="pagination.size"
            :total="pagination.total"
            :page-sizes="[10, 20, 50, 100]"
            layout="total, sizes, prev, pager, next, jumper"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
      </el-card>
    </div>

    <!-- 分类编辑对话框 -->
    <CategoryEditDialog
      v-model:visible="showEditDialog"
      :category="currentCategory"
      :is-edit="isEdit"
      @success="handleEditSuccess"
    />

    <!-- 批量操作确认对话框 -->
    <BatchOperationDialog
      v-model:visible="showBatchDialog"
      :operation-type="batchOperationType"
      :selected-categories="selectedCategories"
      @confirm="handleBatchConfirm"
    />

    <!-- 统计信息对话框 -->
    <CategoryStatisticsDialog v-model:visible="showStatistics" />
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted } from "vue";
import { debounce } from "@pureadmin/utils";
import { ElMessage, ElMessageBox } from "element-plus";
import {
  Search,
  Refresh,
  Plus,
  Select,
  Close,
  Delete,
  DataAnalysis,
  Loading,
  Clock
} from "@element-plus/icons-vue";
import {
  getCategoryListApi,
  enableCategoryApi,
  disableCategoryApi,
  deleteCategoryApi,
  updateCategorySortApi,
  batchOperateCategoriesApi,
  type CategoryInfo,
  type CategoryListQuery,
  CategoryManagementUtils
} from "@/api/category-management";
import CategoryEditDialog from "./components/CategoryEditDialog.vue";
import BatchOperationDialog from "./components/BatchOperationDialog.vue";
import CategoryStatisticsDialog from "./components/CategoryStatisticsDialog.vue";

// 响应式数据
const loading = ref(false);
const tableData = ref<CategoryInfo[]>([]);
const selectedCategories = ref<CategoryInfo[]>([]);
const showEditDialog = ref(false);
const showBatchDialog = ref(false);
const showStatistics = ref(false);
const isEdit = ref(false);
const currentCategory = ref<CategoryInfo | null>(null);
const batchOperationType = ref<string>("ENABLE");

// 正在更新排序的分类ID集合
const updatingSortIds = ref<Set<number>>(new Set());
// 正在编辑排序的分类ID集合（用于显示待保存状态）
const editingSortIds = ref<Set<number>>(new Set());

// 搜索表单
const searchForm = reactive<CategoryListQuery>({
  name: "",
  status: undefined,
  includeArticleCount: true
});

const dateRange = ref<[string, string] | null>(null);

// 分页信息
const pagination = reactive({
  current: 1,
  size: 10,
  total: 0
});

// 计算属性
const hasSelection = computed(() => selectedCategories.value.length > 0);

// 方法
const loadData = async () => {
  loading.value = true;
  try {
    const params: CategoryListQuery = {
      current: pagination.current,
      size: pagination.size,
      ...searchForm
    };

    if (dateRange.value) {
      params.startTime = dateRange.value[0];
      params.endTime = dateRange.value[1];
    }

    const data = await getCategoryListApi(params);

    if (data && data.code === 200) {
      tableData.value = data.data.records;
      pagination.total = data.data.total;
    } else {
      ElMessage.error(data?.message || "获取分类列表失败");
    }
  } catch (error) {
    console.error("获取分类列表失败:", error);
    ElMessage.error("获取分类列表失败");
  } finally {
    loading.value = false;
  }
};

const handleSearch = () => {
  pagination.current = 1;
  loadData();
};

const handleReset = () => {
  Object.assign(searchForm, {
    name: "",
    status: undefined,
    includeArticleCount: true
  });
  dateRange.value = null;
  pagination.current = 1;
  loadData();
};

const handleRefresh = () => {
  loadData();
};

const handleCreate = () => {
  currentCategory.value = null;
  isEdit.value = false;
  showEditDialog.value = true;
};

const handleEdit = (category: CategoryInfo) => {
  currentCategory.value = category;
  isEdit.value = true;
  showEditDialog.value = true;
};

const handleEditSuccess = () => {
  loadData();
};

const handleSelectionChange = (selection: CategoryInfo[]) => {
  selectedCategories.value = selection;
};

const handleSortChange = ({ prop, order }: any) => {
  if (prop && order) {
    searchForm.sortField = prop;
    searchForm.sortOrder = order === "ascending" ? "asc" : "desc";
    loadData();
  }
};

const handleSizeChange = (size: number) => {
  pagination.size = size;
  pagination.current = 1;
  loadData();
};

const handleCurrentChange = (current: number) => {
  pagination.current = current;
  loadData();
};

const handleEnable = async (category: CategoryInfo) => {
  try {
    await ElMessageBox.confirm(
      `确定要启用分类"${category.name}"吗？`,
      "确认操作",
      {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }
    );

    const data = await enableCategoryApi(category.id);

    if (data && data.code === 200) {
      ElMessage.success("分类启用成功");
      loadData();
    } else {
      ElMessage.error(data?.message || "分类启用失败");
    }
  } catch (error) {
    if (error !== "cancel") {
      console.error("启用分类失败:", error);
      ElMessage.error("启用分类失败");
    }
  }
};

const handleDisable = async (category: CategoryInfo) => {
  try {
    await ElMessageBox.confirm(
      `确定要禁用分类"${category.name}"吗？`,
      "确认操作",
      {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }
    );

    const data = await disableCategoryApi(category.id);

    if (data && data.code === 200) {
      ElMessage.success("分类禁用成功");
      loadData();
    } else {
      ElMessage.error(data?.message || "分类禁用失败");
    }
  } catch (error) {
    if (error !== "cancel") {
      console.error("禁用分类失败:", error);
      ElMessage.error("禁用分类失败");
    }
  }
};

const handleDelete = async (category: CategoryInfo) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除分类"${category.name}"吗？删除后不可恢复！`,
      "确认删除",
      {
        confirmButtonText: "确定删除",
        cancelButtonText: "取消",
        type: "error"
      }
    );

    const data = await deleteCategoryApi(category.id);

    if (data && data.code === 200) {
      ElMessage.success("分类删除成功");
      loadData();
    } else {
      ElMessage.error(data?.message || "分类删除失败");
    }
  } catch (error) {
    if (error !== "cancel") {
      console.error("删除分类失败:", error);
      ElMessage.error("删除分类失败");
    }
  }
};

// 存储每个分类的防抖函数
const sortUpdateMap = new Map<number, Function>();

const handleSortOrderChange = (category: CategoryInfo) => {
  // 立即进行前端验证
  const validation = CategoryManagementUtils.validateSortOrder(
    category.sortOrder
  );
  if (!validation.valid) {
    ElMessage.error(validation.message);
    loadData(); // 重新加载数据恢复原值
    return;
  }

  // 标记为正在编辑状态
  editingSortIds.value.add(category.id);

  // 为每个分类创建独立的防抖函数
  if (!sortUpdateMap.has(category.id)) {
    const updateFunc = debounce(
      async (categoryId: number, sortOrder: number) => {
        // 从编辑状态移除，添加到更新状态
        editingSortIds.value.delete(categoryId);
        updatingSortIds.value.add(categoryId);

        try {
          const data = await updateCategorySortApi(categoryId, sortOrder);

          if (data && data.code === 200) {
            ElMessage.success("排序更新成功");
          } else {
            ElMessage.error(data?.message || "排序更新失败");
            loadData(); // 重新加载数据恢复原值
          }
        } catch (error) {
          console.error("更新排序失败:", error);
          ElMessage.error("更新排序失败");
          loadData(); // 重新加载数据恢复原值
        } finally {
          // 完成后从更新状态中移除
          updatingSortIds.value.delete(categoryId);
        }
      },
      800
    );

    sortUpdateMap.set(category.id, updateFunc);
  }

  // 调用对应分类的防抖函数
  const updateFunc = sortUpdateMap.get(category.id);
  if (updateFunc) {
    updateFunc(category.id, category.sortOrder);
  }
};

const handleBatchOperation = (operationType: string) => {
  batchOperationType.value = operationType;
  showBatchDialog.value = true;
};

const handleBatchConfirm = async (params: any) => {
  try {
    const data = await batchOperateCategoriesApi(params);

    if (data && data.code === 200) {
      ElMessage.success("批量操作成功");
      selectedCategories.value = [];
      loadData();
    } else {
      ElMessage.error(data?.message || "批量操作失败");
    }
  } catch (error) {
    console.error("批量操作失败:", error);
    ElMessage.error("批量操作失败");
  }
};

const handleIconError = (event: Event) => {
  const img = event.target as HTMLImageElement;
  // 防止无限循环，检查是否已经是默认图标
  if (img.src.includes("data:image/svg+xml")) {
    return;
  }

  // 使用内联SVG作为默认图标，避免网络请求
  const defaultIcon =
    "data:image/svg+xml;base64," +
    btoa(`
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#909399" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
      <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/>
    </svg>
  `);

  img.src = defaultIcon;
};

// 生命周期
onMounted(() => {
  loadData();
});
</script>

<style scoped>
.category-management {
  padding: 20px;
}

.search-container,
.operation-container,
.table-container {
  margin-bottom: 20px;
}

.operation-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.left-operations,
.right-operations {
  display: flex;
  gap: 8px;
}

.category-name {
  display: flex;
  gap: 8px;
  align-items: center;
}

.category-icon {
  width: 20px;
  height: 20px;
  object-fit: cover;
}

.article-count {
  text-align: center;
}

.article-count .total {
  font-weight: 600;
  color: #303133;
}

.article-count .detail {
  margin-top: 2px;
  font-size: 12px;
  color: #909399;
}

.article-count .detail span {
  display: block;
}

.pagination-container {
  display: flex;
  justify-content: center;
  margin-top: 20px;
}

.sort-input-container {
  position: relative;
  display: flex;
  gap: 8px;
  align-items: center;
}

.sort-loading {
  font-size: 14px;
  color: #409eff;
  animation: rotating 2s linear infinite;
}

.sort-pending {
  font-size: 14px;
  color: #e6a23c;
}

.editing {
  border-color: #e6a23c !important;
  box-shadow: 0 0 0 2px rgb(230 162 60 / 20%) !important;
}

@keyframes rotating {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}
</style>
